/* Copyright [c] 2018-2028 www.chungen90.com Allrights Reserved*/
#include "pch.h"
#include "CGSDLRender.h"
using namespace ChunGen::Client::Player;

	void  callback(void *userdata, Uint8 *stream, int len) {
		if(userdata != nullptr)
		{
			CGBlockRingBuffer* blockingBuffer = (CGBlockRingBuffer*)userdata;
			auto len1 = 0;
			while (len > 0)
			{
				len1 = blockingBuffer->Read((uint8_t*)stream + len1,len);
				len = len - len1;
			}
			
		}
	}

	CGSDLRender::CGSDLRender()
		:blockingBuffer(nullptr)
	{

	}

	CGSDLRender::~CGSDLRender()
	{
		
	}

	int CGSDLRender::InitVideo(HWND hDisplayWindow, int adapterId)
	{
		SDL_Init(SDL_INIT_VIDEO);
		sdlWindow = SDL_CreateWindowFrom(hDisplayWindow);
		sdlRender = SDL_CreateRenderer(sdlWindow, -1, SDL_RendererFlags::SDL_RENDERER_ACCELERATED);
		return S_OK;
	}

	int CGSDLRender::CreateVideoSurface(int width, int height)
	{
		this->width = width;
		this->height = height;
		sdlTexture = SDL_CreateTexture(sdlRender, SDL_PIXELFORMAT_YV12, SDL_TEXTUREACCESS_STREAMING, width, height);
		return S_OK;
	}

	int CGSDLRender::Display(BYTE** data, int* linesize)
	{
		void* piexels = nullptr;
		int pitch;

		int ret = SDL_LockTexture(sdlTexture, NULL, &piexels, &pitch);
		if(ret < 0) return ret;
		uint8_t*	yuv[3] = { 
			(uint8_t*)piexels,(uint8_t*)piexels + pitch * height,
			(uint8_t*)piexels + pitch * height + ((pitch >> 1) * (height >> 1))
		    };
	
			for (int i = 0; i < height; i++)
			{
				memcpy(yuv[0] + i * pitch, data[0] + i * linesize[0], linesize[0]);
				if (i % 2 == 0)
				{
					memcpy(yuv[1] + (i >> 1) * (pitch >> 1), data[2] + (i >> 1) * linesize[2], linesize[2]);
					memcpy(yuv[2] + (i >> 1) * (pitch >> 1), data[1] + (i >> 1) * linesize[1], linesize[1]);
				}
			}
		

		SDL_UnlockTexture(sdlTexture);
		SDL_RenderClear(sdlRender);
		SDL_RenderCopy(sdlRender, sdlTexture, NULL, NULL);
        SDL_RenderPresent(sdlRender);
		return S_OK;
	}



	void CGSDLRender::Close()
	{
		SDL_CloseAudio();
		if(blockingBuffer)
		{
			delete blockingBuffer;
		}
		
	}

	int CGSDLRender::InitAudio(int samples,int channels)
	{
		SDL_Init(SDL_INIT_AUDIO);
		blockingBuffer = new CGBlockRingBuffer();
		blockingBuffer->Init(4 * 1024);
		SDL_AudioSpec wanted;
		wanted.freq = samples;
		wanted.format = AUDIO_S16SYS;
		wanted.channels = channels > 2 ? 2 : channels;
		wanted.silence = 0;
		wanted.samples = 1024;
		wanted.callback = callback;
		wanted.userdata = this->blockingBuffer;
	//	devid_out = SDL_OpenAudioDevice(NULL, SDL_FALSE, &wanted, &spec, SDL_AUDIO_ALLOW_ANY_CHANGE);
		auto r = (SDL_OpenAudio(&wanted,NULL));
		SDL_PauseAudio(0);
		return r;

	}
	int CGSDLRender::PlaySamples(BYTE* buffer, int size) {
		this->blockingBuffer->Write(buffer,size);
		 //SDL_QueueAudio(1,buffer,size);
		return S_OK;
	}
